import { Injectable, NestMiddleware } from '@nestjs/common'
import { ConfigService } from '@nestjs/config'
import { JwtService } from '@nestjs/jwt'
import { IncomingHttpHeaders, IncomingMessage, ServerResponse } from 'http'
import { HEAD_TOKEN } from '../contants/config.contants'
import { JwtExistException, JwtInvalidException } from '../exception/JwtException'
import { ConfigurationKeys } from '../resources'

@Injectable()
export class JwtHandle implements NestMiddleware {
  constructor(private readonly _jwt: JwtService, private readonly config: ConfigService<ConfigurationKeys>) { }

  async use(
    req: IncomingMessage,  // raw request
    res: ServerResponse,   // raw response
    next: () => void,
  ): Promise<void> {
    const token = (req.headers as IncomingHttpHeaders)[HEAD_TOKEN.toLowerCase()] as string | undefined

    if (token) {
      try {
        const secret = this.config.get('jwt.secretkey')
        if (!secret) throw new Error('JWT secret 未配置')
        await this._jwt.verifyAsync(token, { secret, ignoreExpiration: false })
        next()
      } catch {
        throw new JwtInvalidException()
      }
    } else {
      throw new JwtExistException()
    }
  }
}
